package com.echo.sdk.im.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 常用值类型转换 （有限类型）
 *
 * @ClassName: ValueUtils
 * @Description:
 * @author: chentl
 * @date 2016年3月25日 下午4:50:51
 */
public class ValueUtils {

    private static final Logger logger = LoggerFactory.getLogger(ValueUtils.class);


    /**
     * 如果异常，返回0值。
     *
     * @param obj
     * @return
     */
    public static Double parseDoubleForDecorator(Object obj) {
        if (obj == null) {
            return 0d;
        }
        if (obj instanceof Double) {
            return (Double) obj;
        }
        if (obj instanceof String) {
            try {
                return Double.valueOf(obj.toString().trim());
            } catch (NumberFormatException e) {
                logger.error("NumberFormatException ", e);
                return 0d;
            }
        }
        if (obj instanceof Integer) {
            Integer objInt = (Integer) obj;
            return objInt.doubleValue();
        }
        if (obj instanceof Long) {
            Long objLong = (Long) obj;
            return objLong.doubleValue();
        }
        if (obj instanceof BigDecimal) {
            BigDecimal objLong = (BigDecimal) obj;
            return objLong.doubleValue();
        }
        return 0d;
    }


    /**
     * 转换Double
     *
     * @param obj
     * @return return null if parse failed
     * @author zhurui
     * @Description:
     */
    public static Double parseDouble(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof Double) {
            return (Double) obj;
        }
        if (obj instanceof String) {
            try {
                return Double.valueOf(obj.toString().trim());
            } catch (NumberFormatException e) {
                logger.error("NumberFormatException ", e);
                return null;
            }
        }
        if (obj instanceof Integer) {
            Integer objInt = (Integer) obj;
            return objInt.doubleValue();
        }
        if (obj instanceof Long) {
            Long objLong = (Long) obj;
            return objLong.doubleValue();
        }
        if (obj instanceof BigDecimal) {
            return ((BigDecimal) obj).doubleValue();
        }
        return null;
    }

    /**
     * 转换Integer
     *
     * @param obj
     * @return return null if parse failed
     * @Description:
     */
    public static Integer parseInteger(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof Integer) {
            return (Integer) obj;
        }
        if (obj instanceof String) {
            try {
                return Integer.valueOf(obj.toString().trim());
            } catch (NumberFormatException e) {
//                logger.error("NumberFormatException ", e);
                return null;
            }
        }
        if (obj instanceof Double) {
            Double objDouble = (Double) obj;
            return objDouble.intValue();
        }
        if (obj instanceof Long) {
            Long objLong = (Long) obj;
            return objLong.intValue();
        }
        if (obj instanceof Object) {
            return Integer.parseInt(obj.toString());
        }
        return null;
    }

    /**
     * 转换String
     *
     * @param obj
     * @return return null if parse failed
     * @Description:
     */
    public static String parseString(Object obj) {
        if (obj == null) {
            return StringUtils.EMPTY;
        }
        return String.valueOf(obj);
    }

    /**
     * 转换Long
     *
     * @param obj
     * @return return null if parse failed
     * @Description:
     */
    public static Long parseLong(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof Integer) {
            Integer objInt = (Integer) obj;
            return objInt.longValue();
        }
        if (obj instanceof String) {
            try {
                return Long.valueOf(obj.toString().trim());
            } catch (NumberFormatException e) {
                logger.error("NumberFormatException ", e);
                return null;
            }
        }
        if (obj instanceof Double) {
            Double objDouble = (Double) obj;
            return objDouble.longValue();
        }
        if (obj instanceof Long) {
            return (Long) obj;
        }
        return null;
    }

    /**
     * 转换Boolean类型
     *
     * @param obj
     * @return
     * @Description:
     */
    public static Boolean parseBoolean(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof Boolean) {
            return (Boolean) obj;
        }
        if (obj instanceof Integer) {
            Integer objInt = (Integer) obj;
            return objInt != 0;
        }
        if (obj instanceof String) {
            try {
                return Boolean.valueOf(obj.toString().trim());
            } catch (NumberFormatException e) {
                logger.error("NumberFormatException ", e);
                return null;
            }
        }
        if (obj instanceof Double) {
            Double objDouble = (Double) obj;
            return objDouble != 0D;
        }

        if (obj instanceof Long) {
            Long longObj = (Long) obj;
            return longObj != 0;
        }
        return null;
    }

    /**
     * 格式化小数字符串
     *
     * @param obj
     * @param w   保留小数位数
     * @return
     */
    public static String parseFloatString(Object obj, int w) {
        if (obj == null) {
            return StringUtils.EMPTY;
        }

        final double zVal = .0d;
        double val = zVal;
        try {
            val = Double.parseDouble(obj.toString());
        } catch (Exception e) {
            return StringUtils.EMPTY;
        }

        String rStr = "";
        double uVal = .0d;
        if (w == 0) {
            uVal = 1d;
            rStr = "<1";
        } else if (w > 0) {
            final String zStr = String.format("%0" + w + "d", 0);
            uVal = Double.valueOf("." + zStr.substring(1) + "1d");
            rStr = "<" + uVal;
        } else {
            return StringUtils.EMPTY;
        }

        return (val > zVal && val < uVal) ? rStr : String.format("%." + w + "f", obj);
    }

    public static Integer parseInt(Object obj) {
        double value = parseDouble(obj);
        return parseInteger(value);
    }


    public static BigDecimal RetainBigDecimals(BigDecimal bigDecimal) {
        if (bigDecimal == null) {
            return bigDecimal;
        } else {
            return bigDecimal.setScale(4, BigDecimal.ROUND_UP);
        }
    }


    public static String Retain2BigDecimals(String value) {
        if (StringUtils.isNotBlank(value)) {
            try {
                return new BigDecimal(value).setScale(2, BigDecimal.ROUND_DOWN).toString();
            } catch (Exception e) {
                return "";
            }
        } else {
            return value;
        }
    }


    /**
     * 转换cm3 为 m3
     *
     * @param value
     * @return
     */
    public static BigDecimal transferCubicMeter(BigDecimal value, Integer baseNumber, Integer pow) {
        if (value == null) {
            logger.error("params obj is null");
            return null;
        }
        return value.multiply(new BigDecimal(Math.pow(baseNumber, pow))).setScale(4, BigDecimal.ROUND_HALF_UP);
    }

    public static String clearMiddleBrackets(String str) {
        return str.replaceAll("\\[([^\\]]*)\\]", "$1");
    }

    public static String clearMiddleBracketsCN(String str) {
        return str.replaceAll("\\【([^\\】]*)\\】", "$1");
    }


    public static <T, F> boolean compareValue(T t, F f) {
        return t.equals(f);
    }

    public static String replaceBlank(String str) {
        String dest = null;
        if (str == null) {
            return dest;
        } else {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
            return dest;
        }
    }
}
